package cn.hg.solon.youcan.framework.directive.common;

import java.util.function.Supplier;

import org.dromara.hutool.core.text.StrValidator;
import org.dromara.hutool.core.util.ObjUtil;
import org.noear.solon.annotation.Inject;

import com.jfinal.template.Env;
import com.jfinal.template.TemplateException;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.Scope;

import cn.hg.solon.youcan.common.constant.CacheConstants;
import cn.hg.solon.youcan.framework.cache.YoucanCacheService;
import cn.hg.solon.youcan.framework.directive.BaseDirective;
import cn.hg.solon.youcan.system.entity.SysConfig;
import cn.hg.solon.youcan.system.service.SysConfigService;

/**
 * @author 胡高
 */
public abstract class BaseConfigDirective extends BaseDirective {


    @Inject
    private SysConfigService configService;

    @Inject
    YoucanCacheService cacheService;

    public abstract String getDirectiveName();

    public abstract String getType();

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.framework.directive.BaseDirective#onRender(com.jfinal.template.Env, com.jfinal.template.stat.Scope, com.jfinal.template.io.Writer)
     */
    @Override
    public void onRender(Env env, Scope scope, Writer writer) {
        String code = this.getParaToString(0, scope);
        if (StrValidator.isBlank(code)) {
            throw new TemplateException("The parameter of #" + this.getDirectiveName() + " directive can not be blank",
                this.location);
        }

        String type = StrValidator.isBlank(this.getParaToString("type", scope)) ? this.getDirectiveName()
            : this.getParaToString("type", scope);

        SysConfig config = this.cacheService.getOrStoreTag(this.getType() + ":" + code, CacheConstants.CACHE_SECONDS_ONE_DAY, new Supplier<SysConfig>() {
            @Override
            public SysConfig get() {
                return BaseConfigDirective.this.configService.getByTypeAndCode(type, code);
            }
        } , CacheConstants.SYS_DICT_TAG);

        try {
            if (ObjUtil.isNotNull(config)) {
                writer.write(config.getValue());
            }
        } catch (Exception e) {
            throw new TemplateException(e.getMessage(), this.location, e);
        }
    }

}
